#include <gtest/gtest.h>

#include <climits>
#include <cstddef>

#include "list/circular_list.h"

class CirucularTest : public ::testing::Test
{
  protected:
    void SetUp() override
    {
        // 初始化代码 (需要时)
    }
};

static void printCirucularList(ListNode* head)
{
    if (nullptr == head)
        return;
    if (nullptr == head->next)
    {
        std::cout << head->data << std::endl;
        return;
    }

    std::cout << head->data << " ";

    ListNode *p, *q;
    p = q = head->next;

    while (q != nullptr && q->next != p)
    {
        std::cout << q->data << " ";
        q = q->next;
    }

    std::cout << q->data;
    std::cout << std::endl;
}

static void deleteCirucularList(ListNode*& head)
{
    if (nullptr == head || nullptr == head->next)
    {
        delete head;
        head = nullptr;
    }

    ListNode *p, *q;
    q = p = head->next;
    {
        delete head;
        head = nullptr;
    }

    while (q != nullptr && q->next != p)
    {
        ListNode* tmp = q->next;
        delete q;
        q = tmp;
    }

    delete q;
    q = nullptr;
}

TEST_F(CirucularTest, BasicTest)
{
    ListNode* head = new ListNode(0);
    ListNode* node1 = new ListNode(1);
    ListNode* node2 = new ListNode(2);
    ListNode* node3 = new ListNode(3);

    head->next = node1;
    node1->next = node2;
    node2->next = node3;

    node3->next = node1;

    printCirucularList(head);

    EXPECT_TRUE(getCircularListFirstHead(head)->data == 1);

    std::cout << "prepare to delete list" << std::endl;

    deleteCirucularList(head);
}